#include "videoplayer.h"
#include <stdio.h>
#include <QDebug>

extern "C"
{
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libavutil/pixfmt.h"
    #include "libswscale/swscale.h"
}

VideoPlayer::VideoPlayer()
{

}

VideoPlayer::~VideoPlayer()
{

}

void VideoPlayer::run()
{
//    char *file_path = "D:\\MyCenter\\MyStudy\\ffmpeg-3.4\\qtPro\\showAV\\test.ts";
    char *file_path = "udp://192.168.1.4:1008";

    AVFormatContext *pFormatCtx;
    AVCodecContext *pCodecCtx;
    AVCodec *pCodec;
    AVFrame *pFrame;
    AVPacket *packet;

    int videoStream, i;
    int ret, got_picture;

    av_register_all(); //初始化FFMPEG  调用了这个才能正常适用编码器和解码器
    avformat_network_init();

    //Allocate an AVFormatContext.
    pFormatCtx = avformat_alloc_context();

    if (avformat_open_input(&pFormatCtx, file_path, NULL, NULL) != 0)
    {
        printf("can't open the file.");
        return;
    }

    if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
        printf("Could't find stream infomation.");
        return;
    }

    videoStream = -1;

    ///循环查找视频中包含的流信息，直到找到视频类型的流
    ///便将其记录下来 保存到videoStream变量中
    ///这里我们现在只处理视频流  音频流先不管他
    for (i = 0; i < pFormatCtx->nb_streams; i++) {
        if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStream = i;
        }
    }

    ///如果videoStream为-1 说明没有找到视频流
    if (videoStream == -1) {
        printf("Didn't find a video stream.");
        return;
    }

    ///查找解码器
    pCodecCtx = pFormatCtx->streams[videoStream]->codec;
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);

    if (pCodec == NULL) {
        printf("Codec not found.");
        return;
    }

    ///打开解码器
    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
        printf("Could not open codec.");
        return;
    }

    pFrame = av_frame_alloc();

    int y_size = pCodecCtx->width * pCodecCtx->height;

    packet = (AVPacket *) malloc(sizeof(AVPacket)); //分配一个packet
    av_new_packet(packet, y_size); //分配packet的数据

    while (1)
    {
        if (av_read_frame(pFormatCtx, packet) < 0)
        {
            break; //这里认为视频读取完了
        }
        if (packet->stream_index == videoStream) {
            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
            if (ret < 0) {
                printf("decode error.");
                return;
            }
            if (got_picture) {
                QImage tmpImg((uchar *)(pFrame->data[0]),pCodecCtx->width,pCodecCtx->height,QImage::Format_Grayscale8);
//                QImage tmpImg((uchar *)(pFrame->data[1]),pCodecCtx->width*0.5,pCodecCtx->height*0.5,QImage::Format_Grayscale8);
//                QImage tmpImg((uchar *)(pFrame->data[2]),pCodecCtx->width*0.5,pCodecCtx->height*0.5,QImage::Format_Grayscale8);

                QImage image = tmpImg.copy(); //把图像复制一份 传递给界面显示
                //QImage image = tmpImg; //把图像复制一份 传递给界面显示
                emit sig_GetOneFrame(image);  //发送信号
            }
        }
        av_free_packet(packet);
    }
    avcodec_close(pCodecCtx);
    avformat_close_input(&pFormatCtx);
}
